package org.dromara.common.web.interceptor

import cn.hutool.core.io.IoUtil
import cn.hutool.core.map.MapUtil
import io.github.oshai.kotlinlogging.KotlinLogging
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.apache.commons.lang3.time.StopWatch
import org.dromara.common.core.utils.StringUtils
import org.dromara.common.json.utils.JsonUtils
import org.dromara.common.web.filter.RepeatedlyRequestWrapper
import org.springframework.http.MediaType
import org.springframework.web.servlet.HandlerInterceptor
import org.springframework.web.servlet.ModelAndView

/**
 * web的调用时间统计拦截器
 *
 * @author LikeYouDo
 * @date 2025/07/27
 */
class PlusWebInvokeTimeInterceptor : HandlerInterceptor {
    companion object {
        private val log = KotlinLogging.logger { }
        private val KEY_CACHE: ThreadLocal<StopWatch> = ThreadLocal<StopWatch>()
    }

    @Throws(Exception::class)
    override fun preHandle(request: HttpServletRequest, response: HttpServletResponse, handler: Any): Boolean {
        val url = request.method + " " + request.requestURI

        // 打印请求参数
        if (isJsonRequest(request)) {
            var jsonParam = ""
            if (request is RepeatedlyRequestWrapper) {
                val reader = request.reader
                jsonParam = IoUtil.read(reader)
            }
            log.info { "[PLUS]开始请求 => URL[$url],参数类型[json],参数:[$jsonParam]" }
        } else {
            val parameterMap = request.parameterMap
            if (MapUtil.isNotEmpty(parameterMap)) {
                val parameters = JsonUtils.toJsonString(parameterMap!!)
                log.info { "[PLUS]开始请求 => URL[$url],参数类型[param],参数:[$parameters]" }
            } else {
                log.info { "[PLUS]开始请求 => URL[$url],无参数" }
            }
        }

        val stopWatch = StopWatch()
        KEY_CACHE.set(stopWatch)
        stopWatch.start()

        return true
    }

    @Throws(Exception::class)
    override fun postHandle(
        request: HttpServletRequest,
        response: HttpServletResponse,
        handler: Any,
        modelAndView: ModelAndView?
    ) {
    }

    @Throws(Exception::class)
    override fun afterCompletion(
        request: HttpServletRequest,
        response: HttpServletResponse,
        handler: Any,
        ex: Exception?
    ) {
        val stopWatch = KEY_CACHE.get()
        if (stopWatch != null) {
            stopWatch.stop()
            log.info { "[PLUS]结束请求 => URL[${request.method + " " + request.requestURI}],耗时:[${stopWatch.duration.toMillis()}]毫秒" }
            KEY_CACHE.remove()
        }
    }

    /**
     * 判断本次请求的数据类型是否为json
     *
     * @param request request
     * @return boolean
     */
    private fun isJsonRequest(request: HttpServletRequest): Boolean {
        val contentType = request.contentType
        if (contentType != null) {
            return StringUtils.startsWithIgnoreCase(contentType, MediaType.APPLICATION_JSON_VALUE)
        }
        return false
    }

}
